import {
	ref,
	reactive,
	onUnmounted,
	provide,
	inject
} from 'vue'

import useStorage from './useStorage'

const SOCKET_URL = 'wss://www.jingzuanhuicui.com/socket'
const HEARTBEAT_INTERVAL = 10000 // 10秒心跳间隔
const PING_MESSAGE = {
	type: 'ping'
}

class SocketService {
	constructor() {
		if (!SocketService.instance) {
			this.socketTask = null
			this.isConnected = ref(false)
			this.messageQueue = reactive([])
			this.reconnectTimer = null
			this.reconnectCount = 0
			this.maxReconnectCount = 10
			this.reconnectInterval = 3000
			this.messageListeners = []
			this.heartbeatTimer = null // 心跳定时器
			this.pongTimeout = null // PONG超时定时器
			SocketService.instance = this
			// this.initSocket()
		}
		return SocketService.instance
	}

	// 初始化WebSocket连接
	initSocket() {
		if (this.isConnected.value) return

		// console.log('尝试连接WebSocket:', SOCKET_URL)

		this.socketTask = uni.connectSocket({
			url: SOCKET_URL,
			success: () => {
				console.log('WebSocket连接创建成功')
			},
			fail: (err) => {
				console.error('WebSocket连接创建失败:', err)
				this._scheduleReconnect()
			}
		})

		this._setupListeners()
	}

	// 设置WebSocket事件监听
	_setupListeners() {
		// 连接成功
		this.socketTask.onOpen(() => {
			// console.log('WebSocket连接已打开')
			this.isConnected.value = true
			this.reconnectCount = 0
			this._startHeartbeat() // 连接成功后开始心跳
			this._sendQueuedMessages()
		})

		// 收到消息
		this.socketTask.onMessage((res) => {
			// console.log('收到WebSocket消息:', res.data)

			// 处理PONG响应
			try {
				const message = JSON.parse(res.data)

				// console.log('socket.js===', message);
				if (message.type === 'init') {
					this.sendMessage({
						type: 'bind',
						appid: 'wx8e5f8f55c020bf36',
						token: useStorage.get('token')
					});
				}
				if (message.type === 'pong') {
					this._handlePong()
					return
				}
			} catch (e) {
				console.log('非JSON消息:', res.data)
			}

			this.messageListeners.forEach(listener => listener(res.data))
			this.messageQueue.push(res.data)
		})

		// 连接关闭
		this.socketTask.onClose((res) => {
			console.log('WebSocket连接已关闭:', res)
			this.isConnected.value = false
			this._stopHeartbeat() // 连接关闭时停止心跳
			this._scheduleReconnect()
		})

		// 连接错误
		this.socketTask.onError((err) => {
			console.error('WebSocket连接错误:', err)
			this.isConnected.value = false
			this._stopHeartbeat() // 连接错误时停止心跳
			this._scheduleReconnect()
		})
	}

	// 开始心跳
	_startHeartbeat() {
		this._stopHeartbeat() // 先清除现有定时器

		this.heartbeatTimer = setInterval(() => {
			if (this.isConnected.value) {
				// console.log('发送心跳包:', PING_MESSAGE)
				this.sendMessage(PING_MESSAGE)

				// 设置PONG超时检测
				// this._startPongTimeout()
			}
		}, HEARTBEAT_INTERVAL)

		// console.log('心跳机制已启动，间隔:', HEARTBEAT_INTERVAL / 1000, '秒')
	}

	// 停止心跳
	_stopHeartbeat() {
		clearInterval(this.heartbeatTimer)
		clearTimeout(this.pongTimeout)
		this.heartbeatTimer = null
		this.pongTimeout = null
	}

	// 启动PONG超时检测
	_startPongTimeout() {
		// 假设服务器在5秒内应该响应PONG
		this.pongTimeout = setTimeout(() => {
			// console.warn('PONG超时，关闭连接')
			this.socketTask.close() // 关闭连接，触发重连机制
		}, 5000)
	}

	// 处理PONG响应
	_handlePong() {
		// console.log('收到PONG响应')
		clearTimeout(this.pongTimeout) // 清除超时定时器
	}

	// 发送消息
	sendMessage(message) {
		// console.log('准备发送消息.socket.js===', message);

		if (!this.isConnected.value) {
			this.messageQueue.push(message)
			this.initSocket()
			return
		}

		this.socketTask.send({
			data: typeof message === 'string' ? message : JSON.stringify(message),
			success: () => {
				// console.log('消息发送成功', message)
			},
			fail: (err) => {
				console.error('消息发送失败:', err)
				// this.messageQueue.push(message)
			}
		})
	}

	// 注册消息监听器
	onMessage(callback) {
		this.messageListeners.push(callback)

		// 返回取消监听函数
		return () => {
			const index = this.messageListeners.indexOf(callback)
			if (index !== -1) {
				this.messageListeners.splice(index, 1)
			}
		}
	}

	// 发送队列中的消息
	_sendQueuedMessages() {
		while (this.messageQueue.length > 0) {
			const message = this.messageQueue.shift()
			this.sendMessage(message)
		}
	}

	// 计划重连
	_scheduleReconnect() {
		if (this.reconnectCount >= this.maxReconnectCount) {
			console.error('达到最大重连次数')
			return
		}

		clearTimeout(this.reconnectTimer)
		this.reconnectTimer = setTimeout(() => {
			this.reconnectCount++
			console.log(`尝试重连 (${this.reconnectCount}/${this.maxReconnectCount})`)
			this.initSocket()
		}, this.reconnectInterval)
	}

	// 关闭连接
	closeSocket() {
		clearTimeout(this.reconnectTimer)
		this._stopHeartbeat()
		if (this.socketTask) {
			this.socketTask.close()
			this.socketTask = null
		}
		this.isConnected.value = false
	}
}

// 创建单例实例
const socketService = new SocketService()

// 插件注册函数
export const SocketPlugin = {
	install(app) {
		app.provide('socket', socketService)

		// 添加全局错误处理
		app.config.errorHandler = (err, instance, info) => {
			console.error('全局错误捕获:', err, info)
		}
	}
}

// 组合式API使用方法
export function useSocket() {
	const socket = inject('socket')

	if (!socket) {
		console.error('SocketService未正确注册，请确保在main.js中调用了app.use(SocketPlugin)')
		return {
			socket: null,
			onMessage: () => {}
		}
	}

	// 监听消息的钩子
	const onMessage = (callback) => {
		return socket.onMessage(callback)
	}

	return {
		socket,
		onMessage
	}
}

export default socketService